package dao

import (
	"context"
	"fmt"
	"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
	"gorm.io/gorm"
	"time"
)

const FollowRelationTableName = "follow_relations"

var ErrFollowerNotFound = gorm.ErrRecordNotFound

type TableStoreFollowRelationDao struct {
	client *tablestore.TableStoreClient
}

func (t *TableStoreFollowRelationDao) CreateFollowRelation(ctx context.Context, c Follow) error {
	req := new(tablestore.UpdateRowRequest)
	change := new(tablestore.UpdateRowChange)
	change.TableName = FollowRelationTableName
	putPk := new(tablestore.PrimaryKey)
	putPk.AddPrimaryKeyColumn("follower", c.Follower)
	putPk.AddPrimaryKeyColumn("followee", c.Followee)
	change.PrimaryKey = putPk
	now := time.Now()
	change.PutColumn("status", int64(FollowRelationStatusActive))
	change.PutColumn("utime", now.Unix())
	change.PutColumn("ctime", now.Unix())
	change.SetCondition(tablestore.RowExistenceExpectation_IGNORE)

	req.UpdateRowChange = change
	_, err := t.client.UpdateRow(req)
	return err
}
func (t *TableStoreFollowRelationDao) FollowRelationDetail(ctx context.Context, follower,
	followee int64) (Follow, error) {
	request := &tablestore.SQLQueryRequest{
		Query: fmt.Sprintf("select * from %s where follower=%d and followee=%d and status=%d",
			FollowRelationTableName, follower, followee, FollowRelationStatusActive),
	}
	resp, err := t.client.SQLQuery(request)
	if err != nil {
		return Follow{}, err
	}
	resultSet := resp.ResultSet
	if resultSet.HasNext() {
		row := resultSet.Next()
		return t.rowToEntity(row), nil
	}
	return Follow{}, ErrFollowerNotFound
}
func (t *TableStoreFollowRelationDao) CntFollower(ctx context.Context, uid int64) (int64, error) {
	request := &tablestore.SQLQueryRequest{
		Query: fmt.Sprintf("select count(follower) as cnt from %s where follower=%d and status=%d",
			FollowRelationTableName, uid, FollowRelationStatusActive),
	}
	resp, err := t.client.SQLQuery(request)
	if err != nil {
		return 0, err
	}
	resultSet := resp.ResultSet
	if resultSet.HasNext() {
		row := resultSet.Next()
		return row.GetInt64ByName("cnt")
	}
	return 0, ErrFollowerNotFound
}
func (t *TableStoreFollowRelationDao) CntFollowee(ctx context.Context, uid int64) (int64, error) {
	request := &tablestore.SQLQueryRequest{
		Query: fmt.Sprintf("select count(followee) as cnt from %s where followee=%d and status=%d",
			FollowRelationTableName, uid, FollowRelationStatusActive),
	}
	resp, err := t.client.SQLQuery(request)
	if err != nil {
		return 0, err
	}
	resultSet := resp.ResultSet
	if resultSet.HasNext() {
		row := resultSet.Next()
		return row.GetInt64ByName("cnt")
	}
	return 0, ErrFollowerNotFound
}
func (t *TableStoreFollowRelationDao) rowToEntity(row tablestore.SQLRow) Follow {
	var res Follow
	res.Id, _ = row.GetInt64ByName("id")
	res.Follower, _ = row.GetInt64ByName("follower")
	res.Followee, _ = row.GetInt64ByName("followee")
	status, _ := row.GetInt64ByName("status")
	res.Status = uint8(status)
	res.Ctime, _ = row.GetInt64ByName("ctime")
	res.Utime, _ = row.GetInt64ByName("utime")
	return res
}
